<template>
  <div>
    <el-upload
      ref="uploada"
      :action="action"
      :accept="accept"
      with-credentials
      :before-upload="beforeUpload"
      :on-preview="handlePreview"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
      :limit="limit"
      :file-list="fileList"
    >
      <el-button size="mini">上传<i class="el-icon-upload el-icon--right" /></el-button>
      <div v-if="tipText || tip" slot="tip" class="el-upload__tip">{{ tipText || `只能上传${accept}文件，且不超过10MB` }}</div>
    </el-upload>
  </div>
</template>

<script>
export default {
  props: {
    tipText: { // 自定义提示语
      type: String,
      default: ''
    },
    index: { // 派发给当前组件索引
      type: Number,
      default: 0
    },
    limit: { // 文件个数限制
      type: Number,
      default: 10
    },
    action: { // 后台URL
      type: String,
      default: ''
    },
    accept: { // 文件类型
      type: String,
      default: '*/*'
    },
    tip: { // 是否展示默认提示语 => 自定义提示语优先级高
      type: Boolean,
      default: false
    },
    preview: { // 点击下载
      type: Boolean,
      default: false
    },
    size: { // 文件大小限制
      type: Number,
      default: 0
    },
    durationUpper: { // 媒体文件最大持续时间 s/秒
      type: Number,
      default: 0
    },
    durationLower: { // 媒体文件最小持续时间 s/秒
      type: Number,
      default: 0
    },
    fileList: { // 回显文件列表
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
    }
  },
  methods: {
    /**
     * 下载点击文件
     */
    handlePreview(event, file, fileList) {
      // console.log('this.preview', event, file, fileList)
      this.preview && event.absUrl && window.open(event.absUrl)
    },
    /**
     * 上传文件之前
     */
    async beforeUpload(file) {
      return new Promise((resolve, reject) => {
        this.$emit('beforeUpload', file, this.index)
        if (this.size && this.size < file.size) {
          this.$notify({
            title: '失败',
            message: '文件超过限制大小',
            type: 'warning',
            duration: 2000
          })
          reject()
        }
        if (this.durationUpper || this.durationLower) {
          this.mediaTime(file).then(t => {
            if ((this.durationUpper && t > this.durationUpper) || (this.durationLower && t < this.durationLower)) {
              // 当前文件持续时间超时 t: 持续时间
              this.$emit('mediaTimeOut', file, t, this.index)
              reject()
            }
            resolve()
          })
        }
        !(this.durationUpper || this.durationLower) && resolve()
      })
    },
    /**
     * 超出文件个数限制
     */
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 ${this.limit} 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`)
    },
    /**
     * 文件上传失败
     */
    handleError() {
      this.$notify({
        title: '失败',
        message: '上传失败',
        type: 'warning',
        duration: 2000
      })
    },
    /**
     * 文件上传成功
     */
    handleSuccess(response, file, fileList) {
      this.$emit('onSuccess', response, file, fileList, this.index)
    },
    /**
     * 文件删除
     */
    handleRemove(file, fileList) {
      this.$emit('onRemove', file, fileList, this.index)
    },
    /**
     * 校验文件是否为媒体文件
     */
    checkMedia(ext) {
      return new Array('video/mp4').includes(ext.toLowerCase())
    },
    /**
     * 校验媒体文件长度
     */
    mediaTime(file) {
      return new Promise((resolve, reject) => {
        if (!this.checkMedia(file.type)) {
          console.log('Not a media file')
          reject(false)
        }
        // audio获取视频的时长
        var url = URL.createObjectURL(file)
        const ae = new Audio(url)
        let duration
        ae.addEventListener('loadedmetadata', function(_event) {
          duration = ae.duration
          resolve(duration)
        })
      })
    }
  }
}
</script>

<style lang="scss">
  .el-upload-list{
    width: 500px;
  }
</style>
